/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.sunsg.okhttptest.Manager;

import android.content.ContentResolver;
import android.database.Cursor;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.Media;
import android.util.Log;

import com.example.sunsg.okhttptest.bean.Image;
import com.example.sunsg.okhttptest.bean.ImageList;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

/**
 * ImageManager is used to retrieve and store images in the media content
 * provider.
 */
public class ImageManager {

	private static final String TAG = "ImageManager";

	// Location
	public static enum DataLocation {
		NONE, INTERNAL, EXTERNAL, ALL
	}

	// Inclusion
	public static final int INCLUDE_IMAGES = (1 << 0);

	// Sort
	public static final int SORT_ASCENDING = 1;
	public static final int SORT_DESCENDING = 2;

	public static final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera";
	public static final String CAMERA_IMAGE_BUCKET_ID = getBucketId(CAMERA_IMAGE_BUCKET_NAME);
	public static final String URI_ALL_MEDIA = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString();
    public static final String DEFAULT_BUCKET_SORT_ORDER = "upper(" + Images.ImageColumns.BUCKET_DISPLAY_NAME + ") ASC";

	/**
	 * Matches code in MediaProvider.computeBucketValues. Should be a common
	 * function.
	 */
	public static String getBucketId(String path) {
		return String.valueOf(path.toLowerCase().hashCode());
	}

	public static final Uri STORAGE_URI = Images.Media.EXTERNAL_CONTENT_URI;

	// ImageListParam specifies all the parameters we need to create an image
	// list (we also need a ContentResolver).
	public static class ImageListParam implements Parcelable {
		public DataLocation mLocation;
		public int mInclusion;
		public int mSort;
		public String mBucketId;

		// This is only used if we are creating a single image list.
		public Uri mSingleImageUri;

		// This is only used if we are creating an empty image list.
		public boolean mIsEmptyImageList;

		public ImageListParam() {
		}

		public void writeToParcel(Parcel out, int flags) {
			out.writeInt(mLocation.ordinal());
			out.writeInt(mInclusion);
			out.writeInt(mSort);
			out.writeString(mBucketId);
			out.writeParcelable(mSingleImageUri, flags);
			out.writeInt(mIsEmptyImageList ? 1 : 0);
		}

		private ImageListParam(Parcel in) {
			mLocation = DataLocation.values()[in.readInt()];
			mInclusion = in.readInt();
			mSort = in.readInt();
			mBucketId = in.readString();
			mSingleImageUri = in.readParcelable(null);
			mIsEmptyImageList = (in.readInt() != 0);
		}

		public String toString() {
			return String.format("ImageListParam{loc=%s,inc=%d,sort=%d,"
							+ "bucket=%s,empty=%b,single=%s}", mLocation, mInclusion,
					mSort, mBucketId, mIsEmptyImageList, mSingleImageUri);
		}

		public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
			public ImageListParam createFromParcel(Parcel in) {
				return new ImageListParam(in);
			}

			public ImageListParam[] newArray(int size) {
				return new ImageListParam[size];
			}
		};

		public int describeContents() {
			return 0;
		}
	}

	/**
	 * OSX requires plugged-in USB storage to have path /DCIM/NNNAAAAA to be
	 * imported. This is a temporary fix for bug#1655552.
	 */
	public static void ensureOSXCompatibleFolder() {
		File nnnAAAAA = new File(Environment.getExternalStorageDirectory()
				.toString() + "/DCIM/100ANDRO");
		if ((!nnnAAAAA.exists()) && (!nnnAAAAA.mkdir())) {
			Log.e(TAG, "create NNNAAAAA file: " + nnnAAAAA.getPath()
					+ " failed");
		}
	}

	/**
	 * @return true if the mimetype is an image mimetype.
	 */
	public static boolean isImageMimeType(String mimeType) {
		return mimeType.startsWith("image/");
	}

	/**
	 * @return true if the mimetype is a video mimetype.
	 */
	/*
	 * This is commented out because isVideo is not calling this now. public
	 * static boolean isVideoMimeType(String mimeType) { return
	 * mimeType.startsWith("video/"); }
	 */

	/**
	 * @return true if the image is an image.
	 */
	public static boolean isImage(Image image) {
		return isImageMimeType(image.getMimeType());
	}

	public static int getExifOrientation(String filepath) {
		int degree = 0;
		ExifInterface exif = null;
		try {
			exif = new ExifInterface(filepath);
		} catch (IOException ex) {
			Log.e(TAG, "cannot read exif", ex);
		}
		if (exif != null) {
			int orientation = exif.getAttributeInt(
					ExifInterface.TAG_ORIENTATION, -1);
			if (orientation != -1) {
				// We only recognize a subset of orientation tag values.
				switch (orientation) {
				case ExifInterface.ORIENTATION_ROTATE_90:
					degree = 90;
					break;
				case ExifInterface.ORIENTATION_ROTATE_180:
					degree = 180;
					break;
				case ExifInterface.ORIENTATION_ROTATE_270:
					degree = 270;
					break;
				}

			}
		}
		return degree;
	}

	// This is the factory function to create an image list.
	public static ImageList makeImageList(ContentResolver cr, ImageListParam param) {
		DataLocation location = param.mLocation;
		int inclusion = param.mInclusion;
		int sort = param.mSort;
		String bucketId = param.mBucketId;
		ImageList list = null;
		if (location != DataLocation.INTERNAL) {
			if ((inclusion & INCLUDE_IMAGES) != 0) {
				list = new ImageList(cr, STORAGE_URI, sort, bucketId);
			}
		}
		return list;
	}

	// This is a convenience function to create an image list from a Uri.
	public static ImageList makeImageList(ContentResolver cr, Uri uri, int sort) {
		String bucketId = uri.getQueryParameter("bucketId");
		return makeImageList(cr, DataLocation.ALL, INCLUDE_IMAGES, sort, bucketId);
	}

	static boolean isSingleImageMode(String uriString) {
		return !uriString
				.startsWith(MediaStore.Images.Media.EXTERNAL_CONTENT_URI
						.toString())
				&& !uriString
						.startsWith(MediaStore.Images.Media.INTERNAL_CONTENT_URI
								.toString());
	}

	public static ImageListParam getImageListParam(DataLocation location,
			int inclusion, int sort, String bucketId) {
		ImageListParam param = new ImageListParam();
		param.mLocation = location;
		param.mInclusion = inclusion;
		param.mSort = sort;
		param.mBucketId = bucketId;
		return param;
	}

	public static ImageListParam getSingleImageListParam(Uri uri) {
		ImageListParam param = new ImageListParam();
		param.mSingleImageUri = uri;
		return param;
	}

	public static ImageListParam getEmptyImageListParam() {
		ImageListParam param = new ImageListParam();
		param.mIsEmptyImageList = true;
		return param;
	}

	public static ImageList makeImageList(ContentResolver cr,
			DataLocation location, int inclusion, int sort, String bucketId) {
		ImageListParam param = getImageListParam(location, inclusion, sort, bucketId);
		return makeImageList(cr, param);
	}

	public static ImageList makeEmptyImageList() {
		return makeImageList(null, getEmptyImageListParam());
	}

	public static ImageList makeSingleImageList(ContentResolver cr, Uri uri) {
		return makeImageList(cr, getSingleImageListParam(uri));
	}

	public static boolean isMediaScannerScanning(ContentResolver cr) {
		boolean result = false;
		Cursor cursor = query(cr, MediaStore.getMediaScannerUri(),
				new String[] { MediaStore.MEDIA_SCANNER_VOLUME }, null, null,
				null);
		if (cursor != null) {
			if (cursor.getCount() == 1) {
				cursor.moveToFirst();
				result = "external".equals(cursor.getString(0));
			}
			cursor.close();
		}

		return result;
	}

	private static Cursor query(ContentResolver resolver, Uri uri,
			String[] projection, String selection, String[] selectionArgs,
			String sortOrder) {
		try {
			if (resolver == null) {
				return null;
			}
			return resolver.query(uri, projection, selection, selectionArgs,
					sortOrder);
		} catch (UnsupportedOperationException ex) {
			return null;
		}

	}
	
    public static HashMap<String, String> getBucketIds(ContentResolver resolver, Uri imageUri) {
        Uri uri = imageUri.buildUpon().appendQueryParameter("distinct", "true").build();
        Cursor cursor = resolver.query(uri,  new String[] { Media.BUCKET_DISPLAY_NAME, Media.BUCKET_ID}, null, null, DEFAULT_BUCKET_SORT_ORDER);
        HashMap<String, String> hash = new HashMap<String, String>();
        if (cursor == null) return hash;
        try {
            while (cursor.moveToNext()) {
                hash.put(cursor.getString(1), cursor.getString(0));
            }
            return hash;
        } finally {
            cursor.close();
        }
    }

}
